package com.zhengjiang.thread;

import java.util.Random;
import java.util.concurrent.*;

/**
 * @author zhengjiang
 * @version 1.0.0
 * @description  任务分拆,将一个任务拆分成多个小任务放到多个处理器核心上并行执行
 * @date 2021/6/13
 **/
public class ForkJoinPoolTest {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
//        recursiveActionTest();
        recursiveTaskTest();
    }



    static void recursiveActionTest() throws InterruptedException {
        //默认创建一个Runtime.getRuntime().availableProcessors() 个并行线程的ForkJoinPool
        ForkJoinPool forkJoinPool = new ForkJoinPool();
//        System.out.println(Runtime.getRuntime().availableProcessors());
        forkJoinPool.submit(new PrintTask(0,300));
        forkJoinPool.awaitTermination(5, TimeUnit.SECONDS);
        forkJoinPool.shutdown();
    }

    static void recursiveTaskTest() throws ExecutionException, InterruptedException {
        int[] arr = new int[100];
        Random random = new Random();
        int total = 0;
        for (int i= 0;i<arr.length;i++){
            int tmp = random.nextInt(20);
            arr[i] = tmp;
            total += tmp;
        }
        System.out.println("初始总数 = " + total);

        ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
        Future<Integer> future = forkJoinPool.submit(new CalTask(arr, 0, arr.length));
        System.out.println("多线程计算 = " + future.get());
        //关闭线程拆池
        forkJoinPool.shutdown();
    }

}


//无返回值的任务
class PrintTask extends RecursiveAction{
    private static final int THRESHOLD = 50;
    private int start;
    private int end;

    public PrintTask(int start,int end){
        this.start = start;
        this.end = end;
    }

    @Override
    protected void compute() {
        if (end - start < THRESHOLD){
            for (int i = start;i<end;i++){
                System.out.println(Thread.currentThread().getName() + "的i值:" + i);
            }
        }else {
            int middle = (start + end) / 2;
            PrintTask left = new PrintTask(start,middle);
            PrintTask right = new PrintTask(middle,end);
            //并行执行2个小任务
            left.fork();
            right.fork();
        }
    }
}

//创建有返回值的任务
class CalTask extends RecursiveTask<Integer>{

    private static final int THRESHOLD = 20;
    private int start;
    private int end;
    private int[] arr;

    public CalTask(int[] arr,int start,int end){
        this.start = start;
        this.end = end;
        this.arr = arr;
    }

    @Override
    protected Integer compute() {
        int sum = 0;
        if (end - start < THRESHOLD){
            for (int i = start; i < end;i++){
                sum += arr[i];
            }
            return sum;
        }else{
            int middle = (start + end) / 2;
            CalTask left = new CalTask(arr,start,middle);
            CalTask right = new CalTask(arr,middle,end);
            //并行执行2个小任务
            left.fork();
            right.fork();
            return left.join() + right.join();
        }
    }
}
